Skip to main content

Overview

The arithmetic module provides homomorphic operations for computing on encrypted data without decryption. All operations preserve the encrypted values while allowing addition, subtraction, multiplication, and scalar operations.

Addition and subtraction

ct_add

Adds two ciphertexts homomorphically.
const PubKey&
required
Public key
const Cipher&
required
First ciphertext operand
const Cipher&
required
Second ciphertext operand
Cipher
Ciphertext encrypting dec(A) + dec(B)

Description

Performs homomorphic addition by:
  1. Fusing the layer graphs of both ciphertexts
  2. Combining edge sets with appropriate layer offset
  3. Adding constant terms: c0 = A.c0 + B.c0
  4. Compacting edges if budget is exceeded
Both ciphertexts must have the same number of slots.
See: arithmetic.hpp:165

ct_sub

Subtracts one ciphertext from another.
const PubKey&
required
Public key
const Cipher&
required
Minuend ciphertext
const Cipher&
required
Subtrahend ciphertext
Cipher
Ciphertext encrypting dec(A) - dec(B)

Description

Computes homomorphic subtraction as ct_add(pk, A, ct_neg(pk, B)). See: arithmetic.hpp:190

ct_neg

Negates a ciphertext.
const PubKey&
required
Public key
const Cipher&
required
Ciphertext to negate
Cipher
Ciphertext encrypting -dec(A)

Description

Negates by scaling with -1. See: arithmetic.hpp:161

Multiplication

ct_mul

Multiplies two ciphertexts homomorphically.
const PubKey&
required
Public key
const Cipher&
required
First ciphertext operand
const Cipher&
required
Second ciphertext operand
size_t
default:"8"
Number of repack edges per product layer (tuning parameter)
Cipher
Ciphertext encrypting dec(A) * dec(B)

Description

Performs homomorphic multiplication by:
  1. Separating constant terms: A = A_g + a0, B = B_g + b0
  2. Creating product layers for all pairs (layer_a, layer_b)
  3. Computing repacked edges: g^B * (R_a * R_b) = target
  4. Adding cross terms: a0 * B_g + b0 * A_g
  5. Setting constant term: c0 = a0 * b0
This creates |A.L| * |B.L| new product layers.
Multiplication significantly increases ciphertext size. Use ct_square when multiplying a ciphertext with itself for better efficiency.
See: arithmetic.hpp:194

ct_square

Squares a ciphertext homomorphically.
const PubKey&
required
Public key
const Cipher&
required
Ciphertext to square
size_t
default:"8"
Number of repack edges per product layer
Cipher
Ciphertext encrypting dec(A)^2

Description

Computes homomorphic squaring more efficiently than ct_mul(pk, A, A, S) by:
  1. Only creating product layers for pairs (i, j) where i ≤ j
  2. Doubling the contribution for off-diagonal pairs: 2 * R_i * R_j
  3. Creating |A.L| * (|A.L| + 1) / 2 layers instead of |A.L|^2
This reduces the number of layers by approximately 50%. See: arithmetic.hpp:227

Scalar operations

ct_mul_const (unsigned)

Multiplies a ciphertext by an unsigned constant.
const PubKey&
required
Public key
const Cipher&
required
Ciphertext operand
uint64_t
required
Unsigned scalar constant
Cipher
Ciphertext encrypting k * dec(A)

Description

Scales all edge weights and the constant term by k. This is a cheap operation that doesn’t create new layers or edges. See: arithmetic.hpp:261

ct_mul_const (signed)

Multiplies a ciphertext by a signed constant.
const PubKey&
required
Public key
const Cipher&
required
Ciphertext operand
int64_t
required
Signed scalar constant
Cipher
Ciphertext encrypting k * dec(A)

Description

Scales the ciphertext by a signed integer, correctly handling negative values. See: arithmetic.hpp:265

ct_div_const

Divides a ciphertext by a constant (field inversion).
const PubKey&
required
Public key
const Cipher&
required
Ciphertext operand
const Fp&
required
Field element divisor (must be non-zero)
Cipher
Ciphertext encrypting dec(A) / k in the field

Description

Scales by the multiplicative inverse of k in the field. Equivalent to ct_scale(pk, A, fp_inv(k)).
The divisor k must be non-zero. Dividing by zero will cause undefined behavior.
See: arithmetic.hpp:257

ct_add_const (unsigned)

Adds an unsigned constant to a ciphertext.
const PubKey&
required
Public key (unused, for API consistency)
const Cipher&
required
Ciphertext operand
uint64_t
required
Unsigned constant to add
Cipher
Ciphertext encrypting dec(A) + k

Description

Adds a plaintext constant by updating the c0 term. No new edges or layers are created. See: arithmetic.hpp:269

ct_add_const (signed)

Adds a signed constant to a ciphertext.
const PubKey&
required
Public key (unused)
const Cipher&
required
Ciphertext operand
int64_t
required
Signed constant to add
Cipher
Ciphertext encrypting dec(A) + k
See: arithmetic.hpp:277

ct_sub_const (unsigned)

Subtracts an unsigned constant from a ciphertext.
const PubKey&
required
Public key
const Cipher&
required
Ciphertext operand
uint64_t
required
Unsigned constant to subtract
Cipher
Ciphertext encrypting dec(A) - k
See: arithmetic.hpp:285

ct_sub_const (signed)

Subtracts a signed constant from a ciphertext.
const PubKey&
required
Public key
const Cipher&
required
Ciphertext operand
int64_t
required
Signed constant to subtract
Cipher
Ciphertext encrypting dec(A) - k
See: arithmetic.hpp:289

ct_scale

Scales a ciphertext by a field element.
const PubKey&
required
Public key (unused)
const Cipher&
required
Ciphertext to scale
const Fp&
required
Field element scalar
Cipher
Ciphertext encrypting s * dec(A)

Description

Multiplies all edge weights and constant terms by the field element s. This is the most general scalar multiplication function. See: arithmetic.hpp:152

Example usage


Performance considerations

Operation costs:
  • Addition/subtraction: O(edges) - very fast
  • Scalar operations: O(edges) - very fast
  • Multiplication: O(layers^2) - expensive, increases depth
  • Square: O(layers^2 / 2) - more efficient than general multiplication
Multiplication creates many new layers. For deep circuits, periodically use ct_recrypt to refresh noise and compact the ciphertext.